--
-- Author:      feilong
-- DateTime:    2019-09-4 15:57:48
-- Description: 游戏主逻辑

local skynet = require("skynet")
local Timer = require("Timer")
local FSM = require("FSM")
-- local reason = require("reason")
-- local constant = require("constant")

--全局变量本地化
local math_floor = math.floor
local math_random = math.random
local math_abs = math.abs
local table_insert = table.insert
local table_remove = table.remove

local DeskBase = import("DeskBase")
local Desk = class("Desk",DeskBase)

--构造函数
function Desk:ctor()
    self.super:ctor()

end

----------------------------------------------------------------------------------------------
---------游戏
---------------------------------------------------------------------------------------------- 
function Desk:start()
    dbglog("___红包风暴活动_开始了__")
    self.super.start(self) --基础的对象里在里面有初始化的了

    --数据初始化
    self:init()
    --状态时间
    self.state_time = { 
    
    }
    --游戏状态
    --state1 --eventName --state2 --callback
    self.state_list = {     
        {"rest",            "to_grant",         "grant",        function() self:onGrant() end },                
        {"grant",           "to_rest",          "rest",         function() self:onRest() end },     
        {"over",            "to_rest",          "rest",         function() self:onRest() end },
        {"rest",            "to_over",          "over",         function() self:onOver() end },
    }
    self.fsm = FSM.new(self.state_list) --状态机
    --启动状态机
    self.fsm:set("over")
    self:changeState("to_rest") 
end

function Desk:init()
    self.open_time_list = {} --触发时间段
    self.act_data = self.config:getActivity()
    self.ac_content = self.act_data.ac_content
    self.all_coins = self.ac_content.all_coins or 20000 --总金额
    self.grant_coins = 0 --已发放金额
    self.vip_range = self.ac_content.vip_range or {}
    --各个vip区间
    self.range_grant_list = {}
    self.max_coins = 0 --最大的红包金额值
    for k, v in pairs(self.vip_range) do        
        self.range_grant_list[k] = 0 --已发放红包数
        if v[3][2] > self.max_coins then 
            self.max_coins = v[3][2]
        end
    end
    --开放的时间段
    self.begin_time = string_time(self.act_data.ac_begin_time)
    self.end_time = string_time(self.act_data.ac_end_time)
    self.start_grant_time = 0 --触发时间
    self.white_hit_list = {} --白名单命中列表
    self.partake_users = {} --参加这一轮的玩家
    self:getOpenTimeList()

end


--一局结束后重置数据
function Desk:reset()

    self.config:reload()
    self.act_data = self.config:getActivity()
    self.open_time_list = {} --触发时间段
    self.ac_content = self.act_data.ac_content
    self.all_coins = self.ac_content.all_coins  or 20000 --总金额
    self.grant_coins = 0 --已发放金额
    self.vip_range = self.ac_content.vip_range or {}
    --各个vip区间
    self.range_grant_list = {}
    self.max_coins = 0 --最大的红包金额值
    for k, v in pairs(self.vip_range) do        
        self.range_grant_list[k] = 0 --已发放红包数
        if v[3][2] > self.max_coins then 
            self.max_coins = v[3][2]
        end
    end
    --开放的时间段
    self.begin_time = string_time(self.act_data.ac_begin_time)
    self.end_time = string_time(self.act_data.ac_end_time)
    self:getOpenTimeList()

    self.start_grant_time = 0 --触发时间
    self.white_hit_list = {} --白名单命中列表

    self.user_manager:clear() --清掉玩家

end

--开放的时间段
function Desk:getOpenTimeList()
    self.open_time_list = {}
    local time_list = string.split(self.ac_content.open_time, ",")
    local today = get_date()
    for k, v in pairs(time_list) do 
        local str = today .. " " .. v
        table_insert(self.open_time_list, string_time(str))
    end
end

--结束的时间截
function Desk:getStateEndTime()
    return self.state_end_time or 0
end

--根据vip范围取红包额度
function Desk:getPackCoin(user)
    local uid = user:getUid()
    local vip_level = user:getVipLevel()
    local vip_range = self.vip_range
    if user:getMaxRedpackNum() <= user:getRedpackNum() then 
        --超过可领取个数
        user:setRedpackCoins(0)
        return 0
    end
    for k, v in pairs(vip_range) do 
        if vip_level >= v[1][1] and vip_level <= v[1][2] then 
            if self.range_grant_list[k] + 1 > v[2] then 
                --已发完
                user:setRedpackCoins(0)
                return 0
            end
            local coins = math_random(v[3][1], v[3][2])
            --是否超过总额
            if coins + self.grant_coins > self.all_coins then 
                user:setRedpackCoins(0)
                return 0
            end            

            self.range_grant_list[k] = self.range_grant_list[k] + 1
            self.grant_coins = self.grant_coins + coins
            user:setRedpackCoins(coins)
            user:setRedpackAllCoins(user:getRedpackAllCoins() + coins)

            return coins
        end
    end
    user:setRedpackCoins(0)
    return 0
end

--白名单
function Desk:checkWhiteName(user)
    local uid = user:getUid()
    local white_list = self.ac_content.white_list or {}
    if user:getMaxRedpackNum() <= user:getRedpackNum() then 
        --超过可领取个数
        user:setRedpackCoins(0)
        return false
    end    
    for k, v in pairs(white_list) do 
        if uid == v.uid then 
            local num = math_random(0, 100)
            if num < v.rate then 
                --命中
                local coins_1 = math_floor(self.max_coins / 2)
                local coins = math_random(coins_1, self.max_coins)
                if coins + self.grant_coins > self.all_coins then 
                    return false
                end            
                table_insert(self.white_hit_list, {uid, coins})     
                local len = #self.vip_range
                self.range_grant_list[len] = self.range_grant_list[len] + 1
                self.grant_coins = self.grant_coins + coins
                user:setRedpackCoins(coins)
                user:setRedpackAllCoins(user:getRedpackAllCoins() + coins)
                -- user:setRedpackNum(user:getRedpackNum() + 1)                                 
                return coins
            end
            return false
        end
    end
    return false
end

--记录写到
function Desk:writeRecord()
    local str_white = nil
    for k, v in pairs(self.white_hit_list) do 
        if not str_white then 
            str_white = table.concat(v, "+")
        else
            str_white = str_white .."," .. table.concat(v, "+")
        end
    end
    local user_num = 0
    for k, v in pairs(self.partake_users) do 
        user_num = user_num + 1
    end
    local data = {}
    data.date = os.date("%Y-%m-%d %H:%M:%S", self.start_grant_time) --日期
    data.grant_coins = self.grant_coins --发放总额
    data.user_num = user_num --参与人数
    data.redpack_num = table.concat(self.range_grant_list, "+") --红包数量等级分布
    data.white_list = str_white or "" --白名单ID及金额
    data.op = "redpack_record"
    dbglog("_____redpack_record__", dump(data))

    billlog(data)

end

--参与的玩家列表
function Desk:addPartakeNum(uid)
    self.partake_users[uid] = true
end



------------------------------------------------------------------
--state
------------------------------------------------------------------
function Desk:onRest()

    self:reset()  
    local countdown = 0
    local time = os.time()
    self.state_end_time = 0
    for k, open_time in pairs(self.open_time_list) do 
        if time == open_time then 
        -- if true then
            --开启红包   
            self:changeState("to_grant")                
            return
        end            
        if time < open_time then 
            countdown = open_time - time
            self.state_end_time = open_time
            break
        end
        if k == #self.open_time_list then 
            --下一天
            open_time = self.open_time_list[1] + 60*60*24
            if open_time <= self.end_time then 
                if time < open_time then 
                    countdown = open_time - time
                    self.state_end_time = open_time
                    break     
                end        
            else 
                --没有活动了     
                self:changeState("to_over")        
                return   
            end
        end
    end   
    
    local function callback()
        print("____state__",self:getStateNum()-1, countdown)
        self:changeState("to_grant")
        return false    
    end

    self:setTimer(countdown, callback)

end

--开启红包
function Desk:onGrant() 
    local countdown = self.ac_content.continue or 60
    self.start_grant_time = os.time()
    self.partake_users = {} --参加这一轮的玩家
    local function callback()
        print("__2__state__",self:getStateNum()-1, countdown)
        self:writeRecord()
        self:changeState("to_rest")
        return false
    end
    self:setTimer(countdown, callback)  

    --测试
    -- global.message_handler:getRedpackAward({uid=100502})    
end

--所有时间段结束了
function Desk:onOver()
    local function callback()
        print("_onOver_3__state__",self:getStateNum()-1, self.countdown, self.act_data.name)
        self.config:reload()
        self.act_data = self.config:getActivity()
        self:getOpenTimeList() --触发时间段    
        -- dbglog("_____self.act_data__", self.act_data)    
        local time = os.time()
        for k, v in pairs(self.open_time_list) do           
            if k == #self.open_time_list then 
                --下一天
                local open_time = self.open_time_list[1] + 60*60*24
                if open_time <= self.end_time then 
                    if time < open_time then 
                        self:changeState("to_rest")
                        return false     
                    end        
                end 
                return true     
            end
        end   
        return true             
    end
    self:setTimer(5, callback, true)    

end




return Desk